package nl.cwi.arne.lts.resource;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

import nl.cwi.arne.lts.LTS;
import nl.cwi.arne.lts.State;
import nl.cwi.arne.lts.Transition;

public class LTSParser {
	
	private static final String COMMA = ",";
	private static final String LPAREN = "(";
	private static final String RPAREN = ")";
	private static final String QUOTE = "\"";
	
	public LTS parse(InputStream in) throws IOException {
		
		LTS lts = new LTS();
		
		BufferedReader reader = new BufferedReader(new InputStreamReader(in));
		String line;
		
		// Read first line:
		line = reader.readLine().trim();
		if (!line.startsWith("des")) throw new IOException();
		line = removeParens(line.substring(3).trim(), LPAREN, RPAREN);
		
		// Read number of states and transitions:
		StringTokenizer tokenizer = new StringTokenizer(line, COMMA);
		int initial = Integer.parseInt(tokenizer.nextToken());
		int transitions = Integer.parseInt(tokenizer.nextToken());
		int states = Integer.parseInt(tokenizer.nextToken());
		
		// Create states:
		for (int i=0; i<states; i++) {
			lts.getStates().add(new State());
		}
		lts.setInitialState(lts.getStates().get(initial));
		
		// Read transitions:
		while ((line=reader.readLine())!=null) {
			line = line.trim();
			if (line.length()==0) continue;
			Transition transition = new Transition();
			tokenizer = new StringTokenizer(removeParens(line, LPAREN, RPAREN), COMMA);
			transition.setSource(lts.getStates().get(Integer.parseInt(tokenizer.nextToken())));
			String label = tokenizer.nextToken();
			while (!label.trim().endsWith(QUOTE)) {
				label = label + COMMA + tokenizer.nextToken();
			}
			transition.setLabel(removeParens(label, QUOTE, QUOTE));
			transition.setTarget(lts.getStates().get(Integer.parseInt(tokenizer.nextToken())));
			lts.getTransitions().add(transition);
		}
		
		if (lts.getTransitions().size()!=transitions) {
			throw new IOException();
		}
		
		reader.close();
		return lts;
		
	}
	
	private String removeParens(String value, String left, String right) throws IOException {
		value = value.trim();
		if (!value.startsWith(left) || !value.endsWith(right)) throw new IOException();
		return value.substring(1,value.length()-1).trim();
	}
	
}
